package com.balance.anole.client.retail.service.impl;

import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.print.PrintService;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRPrintServiceExporter;
import net.sf.jasperreports.engine.export.JRPrintServiceExporterParameter;

import com.balance.anole.client.retail.vo.RetailReceiptPrintVO;
import com.balance.anole.client.retail.vo.RetailReceiptPrintVO.ProductItemDetail;
import com.balance.anole.erp.accessory.model.PrinterConfiguration;
import com.balance.anole.erp.util.NumberUtil;

public class ReceiptPrintService {

	private static ReceiptPrintService instance;

	private PrinterJob job = PrinterJob.getPrinterJob();

	private PrintService selectedPrint;

	private InputStream io;

	private ReceiptPrintService(){
		selectedPrint = PrinterConfiguration.getDefaultPrinter();
	}

	public static ReceiptPrintService getInstance() {
		if (instance == null) {
			synchronized (ReceiptPrintService.class) {
				if (instance == null) {
					instance = new ReceiptPrintService();
				}
			}
		}

		return instance;
	}

	public void destroy(){
		if(io != null){
			try {
				io.close();
			} catch (IOException e) {
			}
		}
	}

	public void print(RetailReceiptPrintVO printVO) throws JRException, PrinterException, FileNotFoundException{
		try{
			if(selectedPrint == null){
				throw new RuntimeException("打印机 " + PrinterConfiguration.getPrinterName() + " 不可用.");
			}

			io =  ReceiptPrintService.class.getClassLoader()
			.getResourceAsStream("receipt.jasper");

			//prepare report
			List<ProductItemDetail> prodItems = printVO.getProductItemDetails();
			JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(prodItems);
			Map<String, Object> reportParam = new HashMap<String, Object>();
			reportParam.put("SUBREPORT_DIR", "/");
			reportParam.put("needPay", printVO.getNeedPay());
			reportParam.put("paid", printVO.getPaid());
			reportParam.put("change", printVO.getChange());
			reportParam.put("receiptSn", printVO.getReceiptSn());
			reportParam.put("cashier", printVO.getCashier());
			reportParam.put("seller", printVO.getSeller());
			reportParam.put("date", printVO.getDate());
			reportParam.put("paymentList", new JRBeanCollectionDataSource(printVO.getPaymentItemDetails()));

			BigDecimal totalPrice = BigDecimal.ZERO;

			for(ProductItemDetail item : prodItems){
				totalPrice = totalPrice.add(new BigDecimal(item.getAmount()));
			}
			reportParam.put("totalAmount", NumberUtil.formatMoney(totalPrice));

			JasperPrint s = JasperFillManager.fillReport(io, reportParam,
					dataSource);
			if(s.getPages().size() > 0){
				job.setPrintService(selectedPrint);
				PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
				MediaSizeName mediaSizeName = MediaSize.findMedia(4, 4,
						MediaPrintableArea.INCH);
				printRequestAttributeSet.add(mediaSizeName);
				printRequestAttributeSet.add(new Copies(1));
				JRPrintServiceExporter exporter;
				exporter = new JRPrintServiceExporter();
				exporter.reset();
				exporter.setParameter(JRExporterParameter.JASPER_PRINT, s);
				/* We set the selected service and pass it as a paramenter */
				exporter.setParameter(
						JRPrintServiceExporterParameter.PRINT_SERVICE, selectedPrint);
				/*exporter
						.setParameter(
								JRPrintServiceExporterParameter.PRINT_SERVICE_ATTRIBUTE_SET,
								selectedPrint.getAttributes());
				exporter
						.setParameter(
								JRPrintServiceExporterParameter.PRINT_REQUEST_ATTRIBUTE_SET,
								printRequestAttributeSet);*/
				exporter.setParameter(
						JRPrintServiceExporterParameter.DISPLAY_PAGE_DIALOG,
						Boolean.FALSE);
				exporter.setParameter(
						JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG,
						Boolean.FALSE);
				exporter.exportReport();
			}
		}finally{
			destroy();
		}
	}
}
